package com.xiao.dynamic_rule.service;

import com.xiao.dynamic_rule.pojo.LogBean;
import com.xiao.dynamic_rule.pojo.RuleParam;
import com.xiao.dynamic_rule.pojo.RuleParamAtomic;
import com.xiao.dynamic_rule.utils.RuleCalcUtil;
import org.apache.flink.api.common.state.ListState;

import java.util.List;

/**
 * 用户行为次序类服务实现类
 */
public class UserActionSequenceQueryServiceStateImpl implements UserActionSequenceQueryService {

    /**
     *查询规则条件中的 行为序列条件并将查询到的最大匹配步骤 set回 规则对象中
     * @param eventState
     * @param ruleParam
     * @return
     */
    @Override
    public boolean queryActionSequence(String deviceId,ListState<LogBean> eventState, RuleParam ruleParam) throws Exception {

        //从传入的条件对象中取出用户的行为条件
        List<RuleParamAtomic> userActionCountParams = ruleParam.getUserActionCountParams();
        //从flink state中取出用户历史数据
        Iterable<LogBean> logBeans = eventState.get();

        //调用helper统计实际匹配的最大步骤号
        int maxStep = queryActionSequenceHelper(userActionCountParams, logBeans);

        //将最大步骤号 set 会条件对象中，方便后面使用
        ruleParam.setUserActionSequenceQueriedMaxStep(ruleParam.getUserActionSequenceQueriedMaxStep() + maxStep);

        //判断最大步骤数是否等于传入条件序列
        return maxStep == userActionCountParams.size();
    }

    /**
     * 统计明细事件中是否匹配到行为序列，并且将最大步骤放回对象中
     * @param userActionCountParams
     * @param logBeans
     * @return
     */
//    public int queryActionSequenceHelper(List<RuleParamAtomic> userActionCountParams,Iterable<LogBean> logBeans){
//        //将iterable转换为list，方便后面拿到下标
//        ArrayList<LogBean> eventList = new ArrayList<>();
//        CollectionUtils.addAll(eventList,logBeans.iterator());
//
//        int index = 0;
//        int maxStep = 0;
//        //遍历传入的条件
//        for (RuleParamAtomic userActionCountParam : userActionCountParams) {
//            boolean isFind = false;
//            //内循环，遍历历史事件
//            for (int i = index;i < eventList.size();i++){
//                LogBean logBean = eventList.get(i);
//                //判断当前的这个事件 logBean是否满足当前规则条件
//                boolean isMatch = RuleCalcUtil.eventBeanMatchEventParam(logBean, userActionCountParam,true);
//                //如果匹配，则最大步骤 +1，更新下一次循环的下标，并跳出本轮循环
//                if (isMatch){
//                    maxStep ++;
//                    index = i+1;
//                    isFind = true;
//                    break;
//                }
//            }
//            //如果将历史事件循环完也没有找到匹配的事件，则直接返回
////            return maxStep;
//            if (!isFind) break; //跳出本层循环
//        }
//
//        return maxStep;
//    }

    //TODO 可以作为面试亮点讲述
    /**
     * 另一种写法的 queryActionSequenceHelper
     * @param userActionCountParams
     * @param logBeans
     * @return
     */
    public int queryActionSequenceHelper(List<RuleParamAtomic> userActionCountParams,Iterable<LogBean> logBeans){
        int maxStep = 0;

        for (LogBean logBean : logBeans) {
            if (RuleCalcUtil.eventBeanMatchEventParam(logBean,userActionCountParams.get(maxStep))){
                maxStep ++;
            }
            if (maxStep == userActionCountParams.size()) break;
        }
        System.out.println("匹配完成，匹配到的最大步骤数="+maxStep + "条件中的步骤数为="+ userActionCountParams.size());
        return maxStep;
    }
}
